#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MySQL游戏管理器
负责整个游戏的状态管理和核心逻辑（基于MySQL数据库）
"""

import time
import logging
from typing import Optional, Dict, Any, List
from ..database import db_manager, GAME_CONFIG
from ..account.account_manager import AccountManager
from ..character.mysql_character_manager import MySQLCharacterManager
from ..idle.mysql_idle_manager import MySQLIdleManager
from ..battle.battle_manager import BattleManager
from ..database.models import Character, Account

class MySQLGameManager:
    """
    基于MySQL的游戏管理器
    """
    
    def __init__(self):
        """
        初始化游戏管理器
        """
        self.logger = logging.getLogger(__name__)
        
        # 测试数据库连接
        if not db_manager.test_connection():
            raise Exception("数据库连接失败，请检查MySQL服务和配置")
        
        # 创建存储过程和触发器
        try:
            db_manager.create_stored_procedures()
        except Exception as e:
            self.logger.warning(f"创建存储过程失败，但不影响游戏运行: {e}")
        
        # 初始化各个管理器
        self.account_manager = AccountManager()
        self.character_manager = MySQLCharacterManager()
        self.idle_manager = MySQLIdleManager()
        self.battle_manager = BattleManager()  # 暂时保持原有的战斗管理器
        
        # 游戏状态
        self.game_state = "login"  # login, menu, character_select, idle, battle
        self.running = True
        self.start_time = time.time()
        
        # 当前会话信息
        self.current_account: Optional[Account] = None
        self.current_character: Optional[Character] = None
        
        # 启动自动结算定时器
        self._start_auto_settlement()
        
        self.logger.info("MySQL游戏管理器初始化完成")
        print("MySQL游戏管理器初始化完成")
    
    def _start_auto_settlement(self):
        """
        启动自动结算过期挂机的定时器
        """
        try:
            # 立即执行一次自动结算
            self.idle_manager.auto_settle_expired_idle()
            
            # 这里可以添加定时器逻辑，每隔一段时间自动结算
            # 由于这是演示版本，暂时只在初始化时执行一次
            
        except Exception as e:
            self.logger.error(f"自动结算启动失败: {e}")
    
    # ==================== 账号管理 ====================
    
    def login(self, username: str, password: str) -> tuple[bool, str]:
        """
        用户登录
        
        Args:
            username: 用户名
            password: 密码
            
        Returns:
            (成功标志, 消息)
        """
        try:
            success, message, account = self.account_manager.login(username, password)
            
            if success and account:
                self.current_account = account
                self.game_state = "menu"
                self.logger.info(f"用户 {username} 登录成功")
                return True, f"欢迎回来，{account.username}！"
            else:
                return False, message
                
        except Exception as e:
            self.logger.error(f"登录失败: {e}")
            return False, f"登录失败: {str(e)}"
    
    def register(self, username: str, password: str, email: str = "") -> tuple[bool, str]:
        """
        用户注册
        
        Args:
            username: 用户名
            password: 密码
            email: 邮箱（可选）
            
        Returns:
            (成功标志, 消息)
        """
        try:
            success, message = self.account_manager.create_account(username, password, email)
            
            if success:
                self.logger.info(f"用户 {username} 注册成功")
                return True, "注册成功！请登录游戏。"
            else:
                return False, message
                
        except Exception as e:
            self.logger.error(f"注册失败: {e}")
            return False, f"注册失败: {str(e)}"
    
    def logout(self) -> tuple[bool, str]:
        """
        用户登出
        
        Returns:
            (成功标志, 消息)
        """
        try:
            if self.current_account:
                # 如果当前有角色在挂机，先停止挂机
                if self.current_character:
                    idle_status = self.idle_manager.get_idle_status(self.current_character)
                    if idle_status['is_idle']:
                        self.idle_manager.stop_idle(self.current_character)
                
                username = self.current_account.username
                self.account_manager.logout(self.current_account.account_id)
                
                self.current_account = None
                self.current_character = None
                self.game_state = "login"
                
                self.logger.info(f"用户 {username} 登出成功")
                return True, "已安全登出"
            else:
                return False, "当前未登录"
                
        except Exception as e:
            self.logger.error(f"登出失败: {e}")
            return False, f"登出失败: {str(e)}"
    
    def get_current_account(self) -> Optional[Account]:
        """
        获取当前账号
        
        Returns:
            当前账号对象或None
        """
        return self.current_account
    
    # ==================== 角色管理 ====================
    
    def get_current_character(self) -> Optional[Character]:
        """
        获取当前角色
        
        Returns:
            当前角色对象或None
        """
        return self.current_character
    
    def create_character(self, name: str, character_class: str = "战士") -> tuple[bool, str]:
        """
        创建角色
        
        Args:
            name: 角色名
            character_class: 角色职业
            
        Returns:
            (成功标志, 消息)
        """
        if not self.current_account:
            return False, "请先登录"
        
        try:
            # 设置角色管理器的账号ID
            self.character_manager.set_account_id(self.current_account.account_id)
            
            success, message, character = self.character_manager.create_character(
                name, character_class
            )
            
            if success and character:
                self.logger.info(f"角色 {name} 创建成功")
                return True, f"角色 {name} 创建成功！"
            else:
                return False, message
                
        except Exception as e:
            self.logger.error(f"创建角色失败: {e}")
            return False, f"创建角色失败: {str(e)}"
    
    def select_character(self, char_id: int) -> tuple[bool, str]:
        """
        选择角色
        
        Args:
            char_id: 角色ID
            
        Returns:
            (成功标志, 消息)
        """
        if not self.current_account:
            return False, "请先登录"
        
        try:
            character = self.character_manager.get_character(char_id)
            
            if character and character.account_id == self.current_account.account_id:
                self.current_character = character
                self.character_manager.set_current_character(char_id)
                
                self.logger.info(f"选择角色: {character.name}")
                return True, f"已选择角色: {character.name}"
            else:
                return False, "角色不存在或不属于当前账号"
                
        except Exception as e:
            self.logger.error(f"选择角色失败: {e}")
            return False, f"选择角色失败: {str(e)}"
    
    def get_account_characters(self) -> List[Character]:
        """
        获取当前账号的所有角色
        
        Returns:
            角色列表
        """
        if not self.current_account:
            return []
        
        try:
            return self.character_manager.get_account_characters(self.current_account.account_id)
        except Exception as e:
            self.logger.error(f"获取角色列表失败: {e}")
            return []
    
    def delete_character(self, char_id: int) -> tuple[bool, str]:
        """
        删除角色
        
        Args:
            char_id: 角色ID
            
        Returns:
            (成功标志, 消息)
        """
        if not self.current_account:
            return False, "请先登录"
        
        try:
            # 检查角色是否属于当前账号
            character = self.character_manager.get_character(char_id)
            if not character or character.account_id != self.current_account.account_id:
                return False, "角色不存在或不属于当前账号"
            
            # 如果是当前选中的角色，先取消选择
            if self.current_character and self.current_character.char_id == char_id:
                self.current_character = None
            
            success, message = self.character_manager.delete_character(char_id)
            
            if success:
                self.logger.info(f"角色 {character.name} 删除成功")
                return True, f"角色 {character.name} 已删除"
            else:
                return False, message
                
        except Exception as e:
            self.logger.error(f"删除角色失败: {e}")
            return False, f"删除角色失败: {str(e)}"
    
    # ==================== 挂机系统 ====================
    
    def start_idle(self, location_id: int) -> tuple[bool, str]:
        """
        开始挂机
        
        Args:
            location_id: 挂机地点ID
            
        Returns:
            (成功标志, 消息)
        """
        if not self.current_character:
            return False, "请先选择角色"
        
        try:
            success, message = self.idle_manager.start_idle(self.current_character, location_id)
            
            if success:
                self.game_state = "idle"
                self.logger.info(f"角色 {self.current_character.name} 开始挂机")
            
            return success, message
            
        except Exception as e:
            self.logger.error(f"开始挂机失败: {e}")
            return False, f"开始挂机失败: {str(e)}"
    
    def stop_idle(self) -> tuple[bool, str, Dict[str, int]]:
        """
        停止挂机
        
        Returns:
            (成功标志, 消息, 收益字典)
        """
        if not self.current_character:
            return False, "请先选择角色", {}
        
        try:
            success, message, rewards = self.idle_manager.stop_idle(self.current_character)
            
            if success:
                self.game_state = "menu"
                # 更新当前角色信息
                self.current_character = self.character_manager.get_character(self.current_character.char_id)
                self.logger.info(f"角色 {self.current_character.name} 停止挂机")
            
            return success, message, rewards
            
        except Exception as e:
            self.logger.error(f"停止挂机失败: {e}")
            return False, f"停止挂机失败: {str(e)}", {}
    
    def get_idle_status(self) -> Optional[Dict[str, Any]]:
        """
        获取挂机状态
        
        Returns:
            挂机状态信息或None
        """
        if not self.current_character:
            return None
        
        try:
            return self.idle_manager.get_idle_status(self.current_character)
        except Exception as e:
            self.logger.error(f"获取挂机状态失败: {e}")
            return None
    
    def get_available_idle_locations(self) -> List[Dict[str, Any]]:
        """
        获取可用的挂机地点
        
        Returns:
            地点列表
        """
        if not self.current_character:
            return []
        
        try:
            return self.idle_manager.get_available_locations(self.current_character)
        except Exception as e:
            self.logger.error(f"获取挂机地点失败: {e}")
            return []
    
    def get_idle_history(self, limit: int = 10) -> List[Dict[str, Any]]:
        """
        获取挂机历史
        
        Args:
            limit: 返回记录数量限制
            
        Returns:
            挂机历史列表
        """
        if not self.current_character:
            return []
        
        try:
            return self.idle_manager.get_idle_history(self.current_character, limit)
        except Exception as e:
            self.logger.error(f"获取挂机历史失败: {e}")
            return []
    
    # ==================== 战斗系统 ====================
    # 注意：战斗系统暂时保持原有逻辑，后续可以扩展为MySQL版本
    
    def create_battle(self, battle_type: str, team: int) -> str:
        """
        创建战斗
        
        Args:
            battle_type: 战斗类型
            team: 队伍编号
            
        Returns:
            战斗ID
        """
        if not self.current_character:
            raise Exception("请先选择角色")
        
        try:
            battle = self.battle_manager.create_battle(battle_type)
            team_name = "a" if team == 1 else "b"
            success, message = self.battle_manager.join_battle(self.current_character, battle.id, team_name)
            
            if not success:
                raise Exception(message)
            
            return battle.id
            
        except Exception as e:
            self.logger.error(f"创建战斗失败: {e}")
            raise
    
    def get_battle(self, battle_id: str) -> Optional[Dict[str, Any]]:
        """
        获取战斗信息
        
        Args:
            battle_id: 战斗ID
            
        Returns:
            战斗信息或None
        """
        try:
            battle = self.battle_manager.get_battle(battle_id)
            if not battle:
                return None
            
            # 转换为GUI期望的格式
            battle_info = battle.get_battle_info()
            return {
                'id': battle_info['id'],
                'type': battle_info['battle_type'],
                'status': battle_info['status'],
                'team1': [{'id': char.id, 'name': char.name} for char in battle.team_a],
                'team2': [{'id': char.id, 'name': char.name} for char in battle.team_b],
                'winner_team': 1 if battle_info['winner'] == 'team_a' else (2 if battle_info['winner'] == 'team_b' else None),
                'end_time': battle_info['finished_at']
            }
            
        except Exception as e:
            self.logger.error(f"获取战斗信息失败: {e}")
            return None
    
    def join_battle(self, battle_id: str, team: int) -> bool:
        """
        加入战斗
        
        Args:
            battle_id: 战斗ID
            team: 队伍编号
            
        Returns:
            成功标志
        """
        if not self.current_character:
            raise Exception("请先选择角色")
        
        try:
            team_name = "a" if team == 1 else "b"
            success, message = self.battle_manager.join_battle(self.current_character, battle_id, team_name)
            
            if not success:
                raise Exception(message)
            
            return True
            
        except Exception as e:
            self.logger.error(f"加入战斗失败: {e}")
            raise
    
    def leave_battle(self) -> bool:
        """
        离开战斗
        
        Returns:
            成功标志
        """
        if not self.current_character:
            raise Exception("请先选择角色")
        
        try:
            success, message = self.battle_manager.leave_battle(self.current_character)
            
            if not success:
                raise Exception(message)
            
            return True
            
        except Exception as e:
            self.logger.error(f"离开战斗失败: {e}")
            raise
    
    def start_battle(self, battle_id: str) -> Optional[Dict[str, Any]]:
        """
        开始战斗
        
        Args:
            battle_id: 战斗ID
            
        Returns:
            战斗结果或None
        """
        try:
            success, message = self.battle_manager.start_battle(battle_id)
            
            if not success:
                raise Exception(message)
            
            # 获取战斗结果
            battle = self.battle_manager.get_battle(battle_id)
            if battle:
                battle_info = battle.get_battle_info()
                return {
                    'winner_team': 1 if battle_info['winner'] == 'team_a' else (2 if battle_info['winner'] == 'team_b' else None),
                    'battle_log': battle_info['battle_log']
                }
            
            return None
            
        except Exception as e:
            self.logger.error(f"开始战斗失败: {e}")
            raise
    
    def get_available_battles(self) -> List[Dict[str, Any]]:
        """
        获取可用战斗列表
        
        Returns:
            战斗列表
        """
        try:
            battles = self.battle_manager.get_available_battles()
            result = []
            
            for battle_info in battles:
                battle = self.battle_manager.get_battle(battle_info['id'])
                if battle:
                    result.append({
                        'id': battle_info['id'],
                        'type': battle_info['battle_type'],
                        'status': battle_info['status'],
                        'team1': [{'id': char.id, 'name': char.name} for char in battle.team_a],
                        'team2': [{'id': char.id, 'name': char.name} for char in battle.team_b]
                    })
            
            return result
            
        except Exception as e:
            self.logger.error(f"获取可用战斗失败: {e}")
            return []
    
    def get_battle_history(self) -> List[Dict[str, Any]]:
        """
        获取战斗历史
        
        Returns:
            战斗历史列表
        """
        try:
            history = self.battle_manager.get_battle_history()
            result = []
            
            for battle_info in history:
                battle = self.battle_manager.get_battle(battle_info['id'])
                if battle:
                    result.append({
                        'id': battle_info['id'],
                        'type': battle_info['battle_type'],
                        'status': battle_info['status'],
                        'team1': [{'id': char.id, 'name': char.name} for char in battle.team_a],
                        'team2': [{'id': char.id, 'name': char.name} for char in battle.team_b],
                        'winner_team': 1 if battle_info['winner'] == 'team_a' else (2 if battle_info['winner'] == 'team_b' else None),
                        'end_time': battle_info['finished_at']
                    })
            
            return result
            
        except Exception as e:
            self.logger.error(f"获取战斗历史失败: {e}")
            return []
    
    # ==================== 游戏统计和管理 ====================
    
    def save_game(self) -> tuple[bool, str]:
        """
        保存游戏数据
        
        Returns:
            (成功标志, 消息)
        """
        try:
            # MySQL版本中数据实时保存，这里主要是触发一些清理工作
            self.idle_manager.auto_settle_expired_idle()
            
            self.logger.info("游戏数据保存完成")
            return True, "游戏数据已保存"
            
        except Exception as e:
            self.logger.error(f"保存游戏数据失败: {e}")
            return False, f"保存失败: {str(e)}"
    
    def get_game_stats(self) -> Dict[str, Any]:
        """
        获取游戏统计信息
        
        Returns:
            统计信息字典
        """
        try:
            play_time = time.time() - self.start_time
            
            # 获取账号统计
            account_stats = {}
            if self.current_account:
                account_stats = self.account_manager.get_account_stats(self.current_account.account_id)
            
            # 获取角色统计
            character_stats = {}
            if self.current_account:
                characters = self.get_account_characters()
                character_stats = {
                    'total_characters': len(characters),
                    'max_level': max([char.level for char in characters]) if characters else 0,
                    'class_distribution': {}
                }
                
                # 统计职业分布
                for char in characters:
                    class_name = char.char_class.value
                    character_stats['class_distribution'][class_name] = character_stats['class_distribution'].get(class_name, 0) + 1
            
            return {
                'play_time': play_time,
                'game_state': self.game_state,
                'account_stats': account_stats,
                'character_stats': character_stats,
                'current_account': self.current_account.username if self.current_account else None,
                'current_character': self.current_character.name if self.current_character else None
            }
            
        except Exception as e:
            self.logger.error(f"获取游戏统计失败: {e}")
            return {
                'play_time': 0,
                'game_state': self.game_state,
                'account_stats': {},
                'character_stats': {},
                'current_account': None,
                'current_character': None
            }
    
    def shutdown(self):
        """
        关闭游戏
        """
        try:
            # 保存游戏数据
            self.save_game()
            
            # 登出当前用户
            if self.current_account:
                self.logout()
            
            # 关闭数据库连接
            db_manager.close_all_connections()
            
            self.running = False
            self.logger.info("游戏已关闭")
            print("游戏已关闭")
            
        except Exception as e:
            self.logger.error(f"关闭游戏失败: {e}")
            print(f"关闭游戏时出错: {e}")
    
    def get_system_info(self) -> Dict[str, Any]:
        """
        获取系统信息
        
        Returns:
            系统信息字典
        """
        try:
            return {
                'database_connected': db_manager.test_connection(),
                'max_idle_hours': GAME_CONFIG['max_idle_hours'],
                'base_exp_per_hour': GAME_CONFIG['base_exp_per_hour'],
                'base_gold_per_hour': GAME_CONFIG['base_gold_per_hour'],
                'version': '2.0.0-mysql',
                'features': ['账号系统', 'MySQL数据库', '常驻挂机', '多角色支持']
            }
            
        except Exception as e:
            self.logger.error(f"获取系统信息失败: {e}")
            return {
                'database_connected': False,
                'error': str(e)
            }